package org.mtmi.ui.controls.popups;

import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.mtmi.ui.IMG;
import org.mtmi.ui.M;
import org.mtmi.ui.actions.IRetargetableAction;
import org.mtmi.ui.actions.RetargetableAction;
import org.mtmi.ui.controls.Control;
import org.mtmi.ui.controls.IContentProvider;
import org.mtmi.ui.controls.ILabelProvider;
import org.mtmi.ui.controls.Keyboard;
import org.mtmi.ui.controls.Knob;
import org.mtmi.ui.controls.LedBargraph;
import org.mtmi.ui.controls.ListView;
import org.mtmi.ui.controls.Slider;
import org.mtmi.ui.controls.Spinner;
import org.mtmi.ui.controls.TrackPad;
import org.mtmi.ui.controls.ValueTransformer;
import org.mtmi.ui.controls.listeners.ISelectionListener;
import org.mtmi.ui.controls.listeners.SelectionEvent;
import org.mtmi.ui.controls.midi.MidiController;
import org.mtmi.ui.controls.midi.MidiKeyboard;
import org.mtmi.ui.drawables.IDrawable;
import org.mtmi.ui.scenes.Scene;

/**
 * Popup displaying a list of control available to populate a scene.
 *
 */
public class AddControlPopup extends AbstractButtonPopup implements  ISelectionListener
{
	
	private static class LabelProvider implements ILabelProvider
	{
		@Override
		public IDrawable getImage(Object element) {
			if( element instanceof IRetargetableAction ) {
				return ((IRetargetableAction)element).getImage();
			}
			return null;
		}

		@Override
		public String getText(Object element) {
			if( element instanceof IRetargetableAction ) {
				return ((IRetargetableAction)element).getText();
			}
			return null;
		}
	}
	
	private class ContentProvider implements IContentProvider
	{
		@Override
		public Object[] getElements(Object input) {
			return creators;
		}
		
	}
	
	private ListView lv_items;
	//private Item  items[];
	private IRetargetableAction  selected;
	
	public AddControlPopup( Scene scene, int flags ) {
		super(scene, "Choose Control:", flags);
	}
	
	@Override
	public Rectangle createContents( Scene _scene )
	{
		lv_items = new ListView( scene, M.SCENE_EDITOR_CONTROL );
		lv_items.addSelectionListener( this );
		lv_items.setLabelProvider( new LabelProvider() );
		lv_items.setContentProvider( new ContentProvider() );
		lv_items.setInput( this );
		
		Point s = scene.getSize();
		int w = s.x/3;
		int h = s.y/2;
		int x = (s.x-w)/2;
		int y = (s.y-h)/2;
		lv_items.setBounds( x, y, w, h );
		
		return new Rectangle( x, y, w, h );
	}
	
	public IRetargetableAction getSelectedAction() {
		return selected;
	}
	
	@Override
	protected void terminate( int id ) {
		lv_items.dispose();
		super.terminate( id );
	}
	
	@Override
	public void selectionChanged( SelectionEvent e ) {
		selected = (IRetargetableAction)e.selection;
	}

	@Override
	public void selectionConfirmed(SelectionEvent e) {
		selected = (IRetargetableAction)e.selection;
		terminate( OK );
	}
	
	private abstract static class CreateControl extends RetargetableAction
	{
		private IDrawable image;
		private String text;
		public CreateControl( String txt, IDrawable img ) {
			super( PUSH, null );
			image = img;
			text = txt;
		}
		@Override
		public IDrawable getImage() { return image; }
		@Override
		public String getText() { return text; }
		@Override
		public final void run() {
			Scene scene = (Scene)getTarget();
			Control c = createControl( scene );
			target = c;
		}
		protected abstract Control createControl( Scene scene );
	}
	
	private static final IRetargetableAction creators [] = new IRetargetableAction[] {
//TODO: USE ControlFactory !!!!!
// => I think this is two different needs, ControlFactory create instance from classes
//    here we maybe interested by various kind of same control class (see Slide,Knob,...)
		new CreateControl( "Slider horizontal", IMG.GetD( IMG.I_SLIDER_H ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new Slider( scene, true, 0,0,100, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Slider vertical", IMG.GetD( IMG.I_SLIDER_V ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new Slider( scene, false, 0,0,100, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Spinner", IMG.GetD( IMG.I_SPINNER ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new Spinner( scene, 0,0,100, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Knob", IMG.GetD( IMG.I_KNOB_PROGRESSIF ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new Knob( scene, 0,0,100, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Knob symetric", IMG.GetD( IMG.I_KNOB_SYMETRIC ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new Knob( scene, 0,-100,100, M.SCENE_CONTROL|Knob.SYMETRIC );
			}
		},
		new CreateControl( "Value Transformer", IMG.GetD( IMG.I_MIDI_VALUE ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new ValueTransformer( scene, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Track Pad", IMG.GetD( IMG.I_TRACKPAD ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new TrackPad( scene, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Led Bargraph", IMG.GetD( IMG.I_TRACKPAD ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new LedBargraph( scene, M.SCENE_CONTROL|M.VERTICAL );
			}
		},
		new CreateControl( "Generic Keyboard", IMG.GetD( IMG.I_KEYBOARD ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new Keyboard( scene, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Midi Keyboard", IMG.GetD( IMG.I_KEYBOARD ) ) {
			@Override
			protected Control createControl(Scene scene) {
				return new MidiKeyboard( scene, M.SCENE_CONTROL );
			}
		},
		new CreateControl( "Midi Controller", null ) {
			@Override
			protected Control createControl(Scene scene) {
				return new MidiController( scene, M.SCENE_CONTROL );
			}
		},
	};
}
